package com.mengniu.commerce.collect.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mengniu.commerce.collect.mapper.SysYzTokenConfigMapper;
import com.mengniu.commerce.collect.model.SysYzTokenConfig;
import com.mengniu.commerce.common.core.constant.RedisKeyConstant;
import com.mengniu.commerce.common.redis.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.management.Query;
import java.sql.Wrapper;
import java.util.concurrent.TimeUnit;


/**
 * @author 13754
 */
@Component
@Slf4j
public class RestTemplateUtil {

    @Resource
    RestTemplate restTemplate;


    @Resource
    private SysYzTokenConfigMapper sysYzTokenConfigMapper;

    public static final String baseURL = "https://open.youzanyun.com/auth/token";

    public static final String CLIENT_ID = "062f406ee377bd9653";

    public static final String CLIENT_SECRET = "4a7803eef189a67c4e4b4b09b8e38cd4";


    public static final String grantType = "client_credentials";

    /***
     * 获取Token
     *  设置过期时间为110分钟 (微盟两小时过期)
     *  更新后重新获取token
     * @param
     * @param
     * ***/
    public String getToken() {
        //查询redis是否有token
        if (RedisUtils.hasKey(RedisKeyConstant.YZ_TOKEN_)) {
            String token = RedisUtils.getCacheObject(RedisKeyConstant.YZ_TOKEN_);
            if (!StringUtils.isEmpty(token)) {
                return token;
            }
        }
        //如果无缓存则刷新重新获取
        String accessToken = "";
        try {
            //从库中获取refreshToken
            SysYzTokenConfig sysYzTokenConfig = sysYzTokenConfigMapper.selectInfo();
            JSONObject js = new JSONObject();
            js.put("client_id", CLIENT_ID);
            js.put("client_secret", CLIENT_SECRET);
            js.put("authorize_type", "refresh_token");
            js.put("refresh_token", sysYzTokenConfig.getRefreshToken());
            JSONObject response = doPost(js, baseURL);
            System.out.println("YZ_TOKEN  result -->" + response);
            if (response.getInteger("code").equals(200)) {
                JSONObject data = response.getJSONObject("data");
                accessToken = data.getString("access_token");
                String refreshToken = data.getString("refresh_token");
                UpdateWrapper<SysYzTokenConfig> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("refresh_token",sysYzTokenConfig.getRefreshToken());
                sysYzTokenConfig.setYzToken(accessToken);
                sysYzTokenConfig.setRefreshToken(refreshToken);
                int update = sysYzTokenConfigMapper.update(sysYzTokenConfig, updateWrapper);
                log.info("有赞token刷新数据落库入参_{},结果_{}", JSONObject.toJSONString(sysYzTokenConfig), update);
                //将token缓存到redis
                if (!accessToken.isEmpty()){
                    RedisUtils.setCacheObject(RedisKeyConstant.YZ_TOKEN_, accessToken, 6L, TimeUnit.DAYS);
                }
            }
        } catch (Exception e) {
            log.error("获取有赞Token出错" + "\nURL:" + baseURL + "\n参数：" + CLIENT_ID + ":" + e);
        }
        return accessToken;
    }


    /***
     *  授权code获取token
     *  设置过期时间为6天（有赞token过期时间7天）
     * @param
     * @param
     * ***/
    public String getTokenByCode(String code) {
        //
        String accessToken = "";
        try {
            JSONObject js = new JSONObject();
            js.put("client_id", CLIENT_ID);
            js.put("client_secret", CLIENT_SECRET);
            js.put("authorize_type", "authorization_code");
            js.put("code", code);
            JSONObject response = doPost(js, baseURL);
            System.out.println("YZ_TOKEN  result -->" + response);
            if (response.getInteger("code").equals(200)) {
                JSONObject data = response.getJSONObject("data");
                accessToken = data.getString("access_token");
                String refreshToken = data.getString("refresh_token");
                //直接清除表中数据 重新生成数据
                int i1 = sysYzTokenConfigMapper.deleteAll();
                //有赞token参数落库
                SysYzTokenConfig sysYzTokenConfig = new SysYzTokenConfig();
                sysYzTokenConfig.setCode(code);
                sysYzTokenConfig.setYzToken(accessToken);
                sysYzTokenConfig.setRefreshToken(refreshToken);
                int i = sysYzTokenConfigMapper.insert(sysYzTokenConfig);
                log.info("有赞token数据落库入参_{},结果_{}", JSONObject.toJSONString(sysYzTokenConfig), i);
                //将token缓存到redis
                if (!accessToken.isEmpty()){
                    RedisUtils.setCacheObject(RedisKeyConstant.YZ_TOKEN_, accessToken, 6L, TimeUnit.DAYS);
                }
            }
        } catch (Exception e) {
            log.error("获取有赞Token出错" + "\nURL:" + baseURL + "\n参数：" + CLIENT_ID + ":" + e);
            throw new RuntimeException(e);
        }
        return accessToken;
    }

    /***
     * 向三方发起请求（json形式）
     * @param
     * @param
     * ***/
    public JSONObject doPost(JSONObject args, String uri) {
        long startTime = System.currentTimeMillis();
        try {
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            HttpEntity<String> requestEntity = new HttpEntity<>(args.toJSONString(), requestHeaders);
            ResponseEntity<String> responseResult = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, String.class);
            long endTime = System.currentTimeMillis();
            String res = responseResult.getBody();
            log.info("\r\n请求三方：" + uri + "，\n参数：\n" + args + "\n返回结果：\n" + JSON.toJSONString(res) + ", 三方请求耗时:" + (endTime - startTime));
            if (res != null) {
                return JSONObject.parseObject(res);
            }
        } catch (Exception e) {
            log.error("向第三方平台提交数据出错" + "\nURL:" + uri + "\n参数：" + args + ":" + e);
        }
        return null;
    }


}
